home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-01-12 | 39.7 KB | 1,402 lines |
- /*
- * @(#)TTY.java 1.63 95/12/09
- *
- * Copyright (c) 1995 Sun Microsystems, Inc. All Rights Reserved.
- *
- * Permission to use, copy, modify, and distribute this software
- * and its documentation for NON-COMMERCIAL purposes and without
- * fee is hereby granted provided that this copyright notice
- * appears in all copies. Please refer to the file "copyright.html"
- * for further important copyright and licensing information.
- *
- * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
- * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
- * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
- * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
- * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
- * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
- */
-
- package sun.tools.ttydebug;
- import sun.tools.debug.*;
- import java.util.*;
- import java.io.*;
- import java.net.*;
-
- public class TTY implements DebuggerCallback {
- RemoteDebugger debugger;
- RemoteThread currentThread;
- RemoteThreadGroup currentThreadGroup;
- PrintStream out = null;
- PrintStream console = null;
-
- private String lastArgs = null;
-
- private RemoteThread indexToThread(int index) throws Exception {
- setDefaultThreadGroup();
- RemoteThread list[] = currentThreadGroup.listThreads(true);
- if (index == 0 || index > list.length) {
- return null;
- }
- return list[index-1];
- }
-
- private int parseThreadId(String idToken) throws Exception {
- if (idToken.startsWith("t@")) {
- idToken = idToken.substring(2);
- }
-
- int threadId;
- try {
- threadId = Integer.valueOf(idToken).intValue();
- } catch (NumberFormatException e) {
- threadId = 0;
- }
- if (indexToThread(threadId) == null) {
- out.println("\"" + idToken +
- "\" is not a valid thread id.");
- return 0;
- }
- return threadId;
- }
-
- private void printPrompt() throws Exception {
- if (currentThread == null) {
- out.print("> ");
- } else {
- out.print(currentThread.getName() + "[" +
- (currentThread.getCurrentFrameIndex() + 1)
- + "] ");
- }
- out.flush();
- }
-
- public synchronized void printToConsole(String text) throws Exception {
- console.print(text);
- console.flush();
- }
-
- public void breakpointEvent(RemoteThread t) throws Exception {
- out.print("\nBreakpoint hit: ");
-
- RemoteStackFrame[] stack = t.dumpStack();
- if (stack.length > 0) {
- out.println(stack[0].toString());
- currentThread = t;
- } else {
- out.println("Invalid thread specified in breakpoint.");
- }
- printPrompt();
- }
-
- public void exceptionEvent(RemoteThread t, String errorText)
- throws Exception {
- out.println("\n" + errorText);
- t.setCurrentFrameIndex(0);
- currentThread = t;
- printPrompt();
- }
-
- public void threadDeathEvent(RemoteThread t) throws Exception {
- out.println("\n" + t.getName() + " died.");
- if (t == currentThread) {
- currentThread = null;
- }
- printPrompt();
- }
-
- public void quitEvent() throws Exception {
- out.println("\nThe application has exited");
- System.exit(0);
- }
-
- void classes() throws Exception {
- RemoteClass list[] = debugger.listClasses();
-
- out.println("** classes list **");
- for (int i = 0 ; i < list.length ; i++) {
- out.println(list[i].description());
- }
- }
-
- void methods(StringTokenizer t) throws Exception {
- if (!t.hasMoreTokens()) {
- out.println("No class specified.");
- return;
- }
-
- String idClass = t.nextToken();
- try {
- RemoteClass cls = getClassFromToken(idClass);
-
- RemoteField methods[] = cls.getMethods();
- for (int i = 0; i < methods.length; i++) {
- out.println(methods[i].getType());
- }
- } catch (IllegalArgumentException e) {
- out.println("\"" + idClass +
- "\" is not a valid id or class name.");
- }
- }
-
- int printThreadGroup(RemoteThreadGroup tg, int iThread) throws Exception {
- out.println("Group " + tg.getName() + ":");
- RemoteThread tlist[] = tg.listThreads(false);
-
- int maxId = 0;
- int maxName = 0;
- for (int i = 0 ; i < tlist.length ; i++) {
- int len = tlist[i].description().length();
- if (len > maxId)
- maxId = len;
- String name = tlist[i].getName();
- int iDot = name.lastIndexOf('.');
- if (iDot >= 0 && name.length() > iDot) {
- name = name.substring(iDot + 1);
- }
- if (name.length() > maxName)
- maxName = name.length();
- }
-
- for (int i = 0 ; i < tlist.length ; i++) {
- char buf[] = new char[80];
- for (int j = 0; j < 79; j++) {
- buf[j] = ' ';
- }
- buf[79] = '\0';
- StringBuffer sbOut = new StringBuffer();
- sbOut.append(buf);
-
- sbOut.insert(((i + iThread + 1) < 10) ? 1 : 0, (i + iThread + 1));
- sbOut.insert(2, ".");
- int iBuf = 4;
- sbOut.insert(iBuf, tlist[i].description());
- iBuf += maxId + 1;
- String name = tlist[i].getName();
- int iDot = name.lastIndexOf('.');
- if (iDot >= 0 && name.length() > iDot) {
- name = name.substring(iDot + 1);
- }
- sbOut.insert(iBuf, name);
- iBuf += maxName + 1;
- sbOut.insert(iBuf, tlist[i].getStatus());
- sbOut.setLength(79);
- out.println(sbOut.toString());
- }
-
- RemoteThreadGroup tglist[] = debugger.listThreadGroups(tg);
- for (int ig = 0; ig < tglist.length; ig++) {
- if (tg != tglist[ig]) {
- iThread += printThreadGroup(tglist[ig], iThread + tlist.length);
- }
- }
- return tlist.length;
- }
-
- private void setDefaultThreadGroup() throws Exception {
- if (currentThreadGroup == null) {
- RemoteThreadGroup tglist[] = debugger.listThreadGroups(null);
- currentThreadGroup = tglist[0]; // system threadgroup
- }
- }
-
- void threads(StringTokenizer t) throws Exception {
- if (!t.hasMoreTokens()) {
- setDefaultThreadGroup();
- printThreadGroup(currentThreadGroup, 0);
- return;
- }
- String name = t.nextToken();
- RemoteThreadGroup tglist[] = debugger.listThreadGroups(null);
- for (int i = 0; i < tglist.length; i++) {
- if (name.equals(tglist[i].getName())) {
- printThreadGroup(tglist[i], 0);
- return;
- }
- }
- out.println(name + " is not a valid threadgroup name.");
- }
-
- void threadGroups() throws Exception {
- RemoteThreadGroup tglist[] = debugger.listThreadGroups(null);
- for (int i = 0; i < tglist.length; i++) {
- out.println(new Integer(i+1).toString() + ". " +
- tglist[i].description() + " " +
- tglist[i].getName());
- }
- }
-
- void setThread(int threadId) throws Exception {
- setDefaultThreadGroup();
- RemoteThread thread = indexToThread(threadId);
- if (thread == null) {
- out.println("\"" + threadId +
- "\" is not a valid thread id.");
- return;
- }
- currentThread = thread;
- }
-
- void thread(StringTokenizer t) throws Exception {
- if (!t.hasMoreTokens()) {
- out.println("Thread number not specified.");
- return;
- }
- int threadId = parseThreadId(t.nextToken());
- if (threadId == 0) {
- return;
- }
- setThread(threadId);
- }
-
- void threadGroup(StringTokenizer t) throws Exception {
- if (!t.hasMoreTokens()) {
- out.println("Threadgroup name not specified.");
- return;
- }
- String name = t.nextToken();
- RemoteThreadGroup tglist[] = debugger.listThreadGroups(null);
- for (int i = 0; i < tglist.length; i++) {
- if (name.equals(tglist[i].getName())) {
- currentThreadGroup = tglist[i];
- return;
- }
- }
- out.println(name + " is not a valid threadgroup name.");
- }
-
- void run(StringTokenizer t) throws Exception {
- String argv[] = new String[100];
- int argc = 0;
-
- if (!t.hasMoreTokens() && lastArgs != null) {
- t = new StringTokenizer(lastArgs);
- out.println("run " + lastArgs);
- }
- while (t.hasMoreTokens()) {
- argv[argc++] = t.nextToken();
- if (argc == 1) {
- // Expand name, if necessary.
- RemoteClass cls = debugger.findClass(argv[0]);
- if (cls == null) {
- out.println("Could not load the " + argv[0] + " class.");
- return;
- }
- argv[0] = cls.getName();
- }
- }
-
- if (argc > 0) {
- RemoteThreadGroup newGroup = debugger.run(argc, argv);
- if (newGroup != null) {
- currentThreadGroup = newGroup;
- setThread(1);
- out.println("running ...");
- } else {
- out.println(argv[0] + " failed.");
- }
- } else {
- out.println("No class name specified.");
- }
- }
-
- void load(StringTokenizer t) throws Exception {
- if (!t.hasMoreTokens()) {
- out.println("Class name not specified.");
- return;
- }
- String idToken = t.nextToken();
- RemoteClass cls = debugger.findClass(idToken);
- if (cls == null) {
- out.print(idToken + " not found");
- out.println((idToken.indexOf('.') > 0) ?
- " (try the full name)" : "");
- } else {
- out.println(cls.toString());
- }
- }
-
- void suspend(StringTokenizer t) throws Exception {
- if (!t.hasMoreTokens()) {
- setDefaultThreadGroup();
- RemoteThread list[] = currentThreadGroup.listThreads(true);
- for (int i = 0; i < list.length; i++) {
- list[i].suspend();
- }
- out.println("All (non-system) threads suspended.");
- } else {
- while (t.hasMoreTokens()) {
- String idToken = t.nextToken();
- int threadId;
- try {
- threadId = Integer.valueOf(idToken).intValue();
- } catch (NumberFormatException e) {
- threadId = 0;
- }
- RemoteThread thread = indexToThread(threadId);
- if (thread == null) {
- out.println("\"" + idToken +
- "\" is not a valid thread id.");
- continue;
- }
- thread.suspend();
- }
- }
- }
-
- void resume(StringTokenizer t) throws Exception {
- if (!t.hasMoreTokens()) {
- setDefaultThreadGroup();
- RemoteThread list[] = currentThreadGroup.listThreads(true);
- for (int i = 0; i < list.length; i++) {
- list[i].resume();
- }
- if (currentThread != null) {
- currentThread.resetCurrentFrameIndex();
- }
- out.println("All threads resumed.");
- } else {
- while (t.hasMoreTokens()) {
- String idToken = t.nextToken();
- int threadId;
- try {
- threadId = Integer.valueOf(idToken).intValue();
- } catch (NumberFormatException e) {
- threadId = 0;
- }
- RemoteThread thread = indexToThread(threadId);
- if (thread == null) {
- out.println("\"" + idToken +
- "\" is not a valid thread id.");
- continue;
- }
- thread.resume();
- if (thread == currentThread) {
- currentThread.resetCurrentFrameIndex();
- }
- }
- }
- }
-
- void cont() throws Exception {
- if (currentThread == null) {
- out.println("Nothing suspended.");
- return;
- }
- setDefaultThreadGroup();
- RemoteThread list[] = currentThreadGroup.listThreads(true);
- for (int i = 0; i < list.length; i++) {
- list[i].cont();
- }
- currentThread.resetCurrentFrameIndex();
- }
-
- void step() throws Exception {
- if (currentThread == null) {
- out.println("Nothing suspended.");
- return;
- }
- try {
- currentThread.step(true);
- } catch (IllegalAccessError e) {
- out.println("Current thread is not at breakpoint.");
- }
- }
-
- void next() throws Exception {
- if (currentThread == null) {
- out.println("Nothing suspended.");
- return;
- }
- try {
- currentThread.next();
- } catch (IllegalAccessError e) {
- out.println("Current thread is not at breakpoint.");
- }
- }
-
- void kill(StringTokenizer t) throws Exception {
- if (!t.hasMoreTokens()) {
- out.println("Usage: kill <threadgroup name> or <thread id>");
- return;
- }
- while (t.hasMoreTokens()) {
- String idToken = t.nextToken();
- int threadId;
- try {
- threadId = Integer.valueOf(idToken).intValue();
- } catch (NumberFormatException e) {
- threadId = 0;
- }
- RemoteThread thread = indexToThread(threadId);
- if (thread != null) {
- out.println("killing thread: " + thread.getName());
- thread.stop();
- return;
- } else {
- /* Check for threadgroup name, skipping "system". */
- RemoteThreadGroup tglist[] = debugger.listThreadGroups(null);
- tglist = debugger.listThreadGroups(tglist[0]);
- for (int i = 0; i < tglist.length; i++) {
- if (tglist[i].getName().equals(idToken)) {
- out.println("killing threadgroup: " + idToken);
- tglist[i].stop();
- return;
- }
- }
-
- out.println("\"" + idToken +
- "\" is not a valid threadgroup or id.");
- }
- }
- }
-
- void catchException(StringTokenizer t) throws Exception {
- if (!t.hasMoreTokens()) {
- String exceptionList[] = debugger.getExceptionCatchList();
- for (int i = 0; i < exceptionList.length; i++) {
- out.print(" " + exceptionList[i]);
- if ((i & 4) == 3 || (i == exceptionList.length - 1)) {
- out.println();
- }
- }
- } else {
- String idClass = t.nextToken();
- try {
- RemoteClass cls = getClassFromToken(idClass);
- cls.catchExceptions();
- } catch (Exception e) {
- out.println("Invalid exception class name: " + idClass);
- }
- }
- }
-
- void ignoreException(StringTokenizer t) throws Exception {
- if (!t.hasMoreTokens()) {
- String exceptionList[] = debugger.getExceptionCatchList();
- for (int i = 0; i < exceptionList.length; i++) {
- out.print(" " + exceptionList[i]);
- if ((i & 4) == 3 || (i == exceptionList.length - 1)) {
- out.println();
- }
- }
- } else {
- String idClass = t.nextToken();
- try {
- RemoteClass cls = getClassFromToken(idClass);
- cls.ignoreExceptions();
- } catch (Exception e) {
- out.println("Invalid exception class name: " + idClass);
- }
- }
- }
-
- void up(StringTokenizer t) throws Exception {
- if (currentThread == null) {
- out.println("Current thread not set.");
- return;
- }
-
- int nLevels = 1;
- if (t.hasMoreTokens()) {
- String idToken = t.nextToken();
- int n;
- try {
- n = Integer.valueOf(idToken).intValue();
- } catch (NumberFormatException e) {
- n = 0;
- }
- if (n == 0) {
- out.println("Usage: up [n frames]");
- return;
- }
- nLevels = n;
- }
-
- try {
- currentThread.up(nLevels);
- } catch (IllegalAccessError e) {
- out.println("Thread isn't suspended.");
- } catch (ArrayIndexOutOfBoundsException e) {
- out.println("End of stack.");
- }
- }
-
- void down(StringTokenizer t) throws Exception {
- if (currentThread == null) {
- out.println("Current thread not set.");
- return;
- }
-
- int nLevels = 1;
- if (t.hasMoreTokens()) {
- String idToken = t.nextToken();
- int n;
- try {
- n = Integer.valueOf(idToken).intValue();
- } catch (NumberFormatException e) {
- n = 0;
- }
- if (n == 0) {
- out.println("usage: down [n frames]");
- return;
- }
- nLevels = n;
- }
-
- try {
- currentThread.down(nLevels);
- } catch (IllegalAccessError e) {
- out.println("Thread isn't suspended.");
- } catch (ArrayIndexOutOfBoundsException e) {
- out.println("End of stack.");
- }
- }
-
- void dumpStack(RemoteThread thread) throws Exception {
- RemoteStackFrame[] stack = thread.dumpStack();
- if (stack.length == 0) {
- out.println("Thread is not running (no stack).");
- } else {
- int nFrames = stack.length;
- for (int i = thread.getCurrentFrameIndex(); i < nFrames; i++) {
- out.print(" [" + (i + 1) + "] ");
- out.println(stack[i].toString());
- }
- }
- }
-
- void where(StringTokenizer t) throws Exception {
- if (!t.hasMoreTokens()) {
- if (currentThread == null) {
- out.println("No thread specified.");
- return;
- }
- dumpStack(currentThread);
- } else {
- String token = t.nextToken();
- if (token.toLowerCase().equals("all")) {
- setDefaultThreadGroup();
- RemoteThread list[] = currentThreadGroup.listThreads(true);
- for (int i = 0; i < list.length; i++) {
- out.println(list[i].getName() + ": ");
- dumpStack(list[i]);
- }
- } else {
- int threadId = parseThreadId(token);
- if (threadId == 0) {
- return;
- }
- dumpStack(indexToThread(threadId));
- }
- }
- }
-
- void trace(String cmd, StringTokenizer t) throws Exception {
- if (!t.hasMoreTokens()) {
- out.println("(i)trace < \"on\" | \"off\" >");
- return;
- }
-
- String v = t.nextToken();
- boolean traceOn;
- if (v.equals("on")) {
- traceOn = true;
- } else if (v.equals("off")) {
- traceOn = false;
- } else {
- out.println("(i)trace < \"on\" | \"off\" >");
- return;
- }
-
- if (cmd.equals("trace")) {
- debugger.trace(traceOn);
- } else {
- debugger.itrace(traceOn);
- }
- }
-
- void memory() throws Exception {
- out.println("Free: " + debugger.freeMemory() + ", total: " +
- debugger.totalMemory());
- }
-
- void gc() throws Exception {
- RemoteObject[] save_list = new RemoteObject[2];
- save_list[0] = currentThread;
- save_list[1] = currentThreadGroup;
- debugger.gc(save_list);
- }
-
- private RemoteClass getClassFromToken(String idToken) throws Exception {
- RemoteObject obj;
- if (idToken.startsWith("0x") ||
- Character.isDigit(idToken.charAt(0))) {
- /* It's an object id. */
- int id;
- try {
- id = RemoteObject.fromHex(idToken);
- } catch (NumberFormatException e) {
- id = 0;
- }
- if (id == 0 || (obj = debugger.get(new Integer(id))) == null) {
- throw new IllegalArgumentException();
- } else if (!(obj instanceof RemoteClass)) {
- throw new IllegalArgumentException();
- }
- } else {
- /* It's a class */
- obj = debugger.findClass(idToken);
- if (obj == null) {
- throw new IllegalArgumentException();
- }
- }
- return (RemoteClass)obj;
- }
-
- void listBreakpoints() throws Exception {
- String bkptList[] = debugger.listBreakpoints();
- if (bkptList.length > 0) {
- out.println("Current breakpoints set:");
- for(int i = 0; i < bkptList.length; i++) {
- out.println("\t" + bkptList[i]);
- }
- } else {
- out.println("No breakpoints set.");
- }
- }
-
- void stop(StringTokenizer t) throws Exception {
- if (!t.hasMoreTokens()) {
- listBreakpoints();
- return;
- }
-
- String idClass = null;
- try {
- String modifier = t.nextToken();
- boolean stopAt;
- if (modifier.equals("at")) {
- stopAt = true;
- } else if (modifier.equals("in")) {
- stopAt = false;
- } else {
- out.println("Usage: stop at <class>:<line_number> or");
- out.println(" stop in <class>.<method_name>");
- return;
- }
-
- if (modifier.equals("at")) {
- idClass = t.nextToken(": \t\n\r");
- RemoteClass cls = getClassFromToken(idClass);
-
- String idLine = t.nextToken();
- int lineno = Integer.valueOf(idLine).intValue();
-
- String err = cls.setBreakpointLine(lineno);
- if (err.length() > 0) {
- out.println(err);
- } else {
- out.println("Breakpoint set at " + cls.getName() +
- ":" + lineno);
- }
- } else {
- idClass = t.nextToken(": \t\n\r");
- RemoteClass cls = null;
- String idMethod = null;
-
- try {
- cls = getClassFromToken(idClass);
- } catch (IllegalArgumentException e) {
- // Try stripping method from class.method token.
- int idot = idClass.lastIndexOf(".");
- if (idot == -1) {
- out.println("\"" + idClass +
- "\" is not a valid id or class name.");
- return;
- }
- idMethod = idClass.substring(idot + 1);
- idClass = idClass.substring(0, idot);
- cls = getClassFromToken(idClass);
- }
-
- if (idMethod == null) {
- idMethod = t.nextToken();
- }
- RemoteField method = cls.getMethod(idMethod);
- if (method == null) {
- out.println("Class " + cls.getName() +
- " doesn't have a method " + idMethod);
- return;
- }
- String err = cls.setBreakpointMethod(method);
- if (err.length() > 0) {
- out.println(err);
- } else {
- out.println("Breakpoint set in " + cls.getName() +
- "." + idMethod);
- }
- }
- } catch (NoSuchElementException e) {
- out.println("Usage: stop at <class>:<line_number> or");
- out.println(" stop in <class>.<method_name>");
- } catch (NumberFormatException e) {
- out.println("Invalid line number.");
- } catch (IllegalArgumentException e) {
- out.println("\"" + idClass +
- "\" is not a valid id or class name.");
- }
- }
-
- void clear(StringTokenizer t) throws Exception {
- if (!t.hasMoreTokens()) {
- listBreakpoints();
- return;
- }
-
- String idClass = null;
- String idMethod = null;
- RemoteClass cls = null;
- try {
- idClass = t.nextToken(": \t\n\r");
- try {
- cls = getClassFromToken(idClass);
- } catch (IllegalArgumentException e) {
- // Try stripping method from class.method token.
- int idot = idClass.lastIndexOf(".");
- if (idot == -1) {
- out.println("\"" + idClass +
- "\" is not a valid id or class name.");
- return;
- }
- idMethod = idClass.substring(idot + 1);
- idClass = idClass.substring(0, idot);
- cls = getClassFromToken(idClass);
- RemoteField method = cls.getMethod(idMethod);
- if (method == null) {
- out.println("\"" + idMethod +
- "\" is not a valid method name of class " +
- cls.getName());
- return;
- }
- String err = cls.clearBreakpointMethod(method);
- if (err.length() > 0) {
- out.println(err);
- } else {
- out.println("Breakpoint cleared at " +
- cls.getName() + "." + idMethod);
- }
- return;
- }
-
- String idLine = t.nextToken();
- int lineno = Integer.valueOf(idLine).intValue();
-
- String err = cls.clearBreakpointLine(lineno);
- if (err.length() > 0) {
- out.println(err);
- } else {
- out.println("Breakpoint cleared at " + cls.getName() +
- ": " + lineno);
- }
- } catch (NoSuchElementException e) {
- out.println("Usage: clear <class>:<line_number>");
- out.println(" or: clear <class>.<method>");
- } catch (NumberFormatException e) {
- out.println("Usage: clear <class>:<line_number>");
- out.println(" or: clear <class>.<method>");
- } catch (IllegalArgumentException e) {
- out.println("\"" + idClass +
- "\" is not a valid id or class name.");
- }
- }
-
- void list(StringTokenizer t) throws Exception {
- RemoteStackFrame frame = null;
- if (currentThread == null) {
- out.println("No thread specified.");
- return;
- }
- try {
- frame = currentThread.getCurrentFrame();
- } catch (IllegalAccessError e) {
- out.println("Current thread isn't suspended.");
- return;
- } catch (ArrayIndexOutOfBoundsException e) {
- out.println("Thread is not running (no stack).");
- return;
- }
-
- int lineno;
- if (t.hasMoreTokens()) {
- String idLine = t.nextToken();
- lineno = Integer.valueOf(idLine).intValue();
- } else {
- lineno = frame.getLineNumber();
- }
- int startLine = (lineno > 4) ? lineno - 4 : 1;
- int endLine = startLine + 9;
-
- InputStream rawSourceFile = frame.getRemoteClass().getSourceFile();
- if (rawSourceFile == null) {
- out.println("Unable to find " +
- frame.getRemoteClass().getSourceFileName());
- return;
- }
-
- DataInputStream sourceFile = new DataInputStream(rawSourceFile);
- String sourceLine = null;
-
- /* Skip through file to desired window. */
- for (int i = 1; i <= startLine; i++) {
- sourceLine = sourceFile.readLine();
- }
- if (sourceLine == null) {
- out.println(new Integer(lineno).toString() +
- " is an invalid line number for the file " +
- frame.getRemoteClass().getSourceFileName());
- }
-
- /* Print lines */
- for (int i = startLine; i < endLine && sourceLine != null; i++) {
- out.print(new Integer(i).toString() + "\t" +
- ((i == lineno) ? "=> " : " "));
- out.println(sourceLine);
- sourceLine = sourceFile.readLine();
- }
-
- }
-
- /* Get or set the source file path list. */
- void use(StringTokenizer t) throws Exception {
- if (!t.hasMoreTokens()) {
- out.println(debugger.getSourcePath());
- } else {
- debugger.setSourcePath(t.nextToken());
- }
- }
-
- /* Print all local variables in current stack frame. */
- void locals() throws Exception {
- if (currentThread == null) {
- out.println("No default thread specified: " +
- "use the \"thread\" command first.");
- return;
- }
- RemoteStackVariable rsv[] = currentThread.getStackVariables();
- if (rsv == null || rsv.length == 0) {
- out.println("No local variables: try compiling with -g");
- return;
- }
- out.println("Local variables and arguments:");
- for (int i = 0; i < rsv.length; i++) {
- out.print(" " + rsv[i].getName());
- if (rsv[i].inScope()) {
- out.println(" = " + rsv[i].getValue().toString());
- } else {
- out.println(" is not in scope.");
- }
- }
- return;
- }
-
- /* Print a specified reference. Returns success in resolving reference. */
- boolean print(StringTokenizer t, boolean dumpObject, boolean recursing) throws Exception {
- if (!t.hasMoreTokens()) {
- out.println("No objects specified.");
- return false;
- }
-
- while (t.hasMoreTokens()) {
- int id;
- RemoteValue obj = null;
-
- String delimiters = ".[(";
- String expr = t.nextToken();
- StringTokenizer pieces =
- new StringTokenizer(expr, delimiters, true);
-
- String idToken = pieces.nextToken(); // There will be at least one.
- String varName = expr;
- if (idToken.startsWith("t@")) {
- /* It's a thread */
- setDefaultThreadGroup();
- RemoteThread tlist[] = currentThreadGroup.listThreads(true);
- try {
- id = Integer.valueOf(idToken.substring(2)).intValue();
- } catch (NumberFormatException e) {
- id = 0;
- }
- if (id <= 0 || id > tlist.length) {
- out.println("\"" + idToken +
- "\" is not a valid thread id.");
- return false;
- }
- obj = tlist[id - 1];
-
- } else if (idToken.startsWith("$s")) {
- int slotnum;
- try {
- slotnum = Integer.valueOf(idToken.substring(2)).intValue();
- } catch (NumberFormatException e) {
- out.println("\"" + idToken +
- "\" is not a valid slot.");
- return false;
- }
- if (currentThread != null) {
- RemoteStackVariable rsv[] = currentThread.getStackVariables();
- if (rsv == null || slotnum >= rsv.length) {
- out.println("\"" + idToken +
- "\" is not a valid slot.");
- return false;
- }
- obj = rsv[slotnum].getValue();
- }
-
- } else if (idToken.startsWith("0x") ||
- Character.isDigit(idToken.charAt(0))) {
- /* It's an object id. */
- try {
- id = RemoteObject.fromHex(idToken);
- } catch (NumberFormatException e) {
- id = 0;
- }
- if (id == 0 || (obj = debugger.get(new Integer(id))) == null) {
- out.println("\"" + idToken +
- "\" is not a valid id.");
- return false;
- }
- } else {
- /* See if it's a local stack variable */
- if (currentThread != null) {
- RemoteStackVariable rsv =
- currentThread.getStackVariable(idToken);
- if (rsv != null && !rsv.inScope()) {
- out.println(idToken + " is not in scope.");
- return false;
- }
- obj = (rsv == null) ? null : rsv.getValue();
- }
- if (obj == null) {
- if (idToken.equals("this") == false) {
- /* See if it's an instance variable */
- String instanceStr = "this." + idToken;
- if (print(new StringTokenizer(instanceStr),
- dumpObject, true))
- return true;
- }
-
- /* It's a class */
- obj = debugger.findClass(idToken);
- if (obj == null) {
- if (!recursing) {
- out.println("\"" + expr + "\" is not a " +
- "valid id or class name.");
- }
- return false;
- }
- }
- }
-
- RemoteInt noValue = new RemoteInt(-1);
- RemoteValue rv = noValue;
- String lastField = "";
- idToken = pieces.hasMoreTokens() ? pieces.nextToken() : null;
- while (idToken != null) {
-
- if (idToken.equals(".")) {
- if (pieces.hasMoreTokens() == false) {
- out.println("\"" + expr +
- "\" is not a valid expression.");
- return false;
- }
- idToken = pieces.nextToken();
-
- if (rv != noValue) {
- /* attempt made to get a field on a non-object */
- out.println("\"" + lastField +
- "\" is not an object.");
- return false;
- }
- lastField = idToken;
-
- rv = ((RemoteObject)obj).getFieldValue(idToken);
- if (rv == null) {
- out.println("\"" + idToken +
- "\" is not a valid field of " +
- obj.description());
- return false;
- }
- if (rv.isObject()) {
- obj = rv;
- rv = noValue;
- }
- idToken =
- pieces.hasMoreTokens() ? pieces.nextToken() : null;
-
- } else if (idToken.equals("[")) {
- if (pieces.hasMoreTokens() == false) {
- out.println("\"" + expr +
- "\" is not a valid expression.");
- return false;
- }
- idToken = pieces.nextToken("]");
- try {
- int index = Integer.valueOf(idToken).intValue();
- rv = ((RemoteArray)rv).getElement(index);
- } catch (NumberFormatException e) {
- out.println("\"" + idToken +
- "\" is not a valid decimal number.");
- return false;
- } catch (ArrayIndexOutOfBoundsException e) {
- out.println(idToken + " is out of bounds for " +
- obj.description());
- return false;
- }
- if (rv != null && rv.isObject()) {
- obj = rv;
- rv = noValue;
- }
- if (pieces.hasMoreTokens() == false ||
- (idToken = pieces.nextToken()).equals("]") == false) {
- out.println("\"" + expr +
- "\" is not a valid expression.");
- return false;
- }
- idToken = pieces.hasMoreTokens() ?
- pieces.nextToken(delimiters) : null;
-
- } else if (idToken.equals("(")) {
- out.println("print <method> not supported yet.");
- return false;
- } else {
- /* Should never get here. */
- out.println("invalid expression");
- return false;
- }
- }
-
- out.print(varName + " = ");
- if (rv != noValue) {
- out.println((rv == null) ? "null" : rv.description());
- } else if (dumpObject && obj instanceof RemoteObject) {
- out.println(obj.description() + " {");
-
- if (obj instanceof RemoteClass) {
- RemoteClass cls = (RemoteClass)obj;
-
- out.print(" superclass = ");
- RemoteClass superClass = cls.getSuperclass();
- out.println((superClass == null) ?
- "null" : superClass.description());
-
- out.print(" loader = ");
- RemoteObject loader = cls.getClassLoader();
- out.println((loader == null) ?
- "null" : loader.description());
-
- RemoteClass interfaces[] = cls.getInterfaces();
- if (interfaces != null && interfaces.length > 0) {
- out.println(" interfaces:");
- for (int i = 0; i < interfaces.length; i++) {
- out.println(" " + interfaces[i]);
- }
- }
- }
-
- RemoteField fields[] = ((RemoteObject)obj).getFields();
- if (obj instanceof RemoteClass && fields.length > 0) {
- out.println();
- }
- for (int i = 0; i < fields.length; i++) {
- String name = fields[i].getType();
- String modifiers = fields[i].getModifiers();
- out.print(" " + modifiers + name + " = ");
- RemoteValue v = ((RemoteObject)obj).getFieldValue(i);
- out.println((v == null) ? "null" : v.description());
- }
- out.println("}");
- } else {
- out.println(obj.toString());
- }
- }
- return true;
- }
-
- void help
- () {
- out.println("** command list **");
- out.println("threads [threadgroup] -- list threads");
- out.println("thread <thread id> -- set default thread");
- out.println("suspend [thread id(s)] -- suspend threads (default: all)");
- out.println("resume [thread id(s)] -- resume threads (default: all)");
- out.println("where [thread id] | all -- dump a thread's stack");
- out.println("threadgroups -- list threadgroups");
- out.println("threadgroup <name> -- set current threadgroup\n");
- out.println("print <id> [id(s)] -- print object or field");
- out.println("dump <id> [id(s)] -- print all object information\n");
- out.println("locals -- print all local variables in current stack frame\n");
- out.println("classes -- list currently known classes");
- out.println("methods <class id> -- list a class's methods\n");
- out.println("stop in <class id>.<method> -- set a breakpoint in a method");
- out.println("stop at <class id>:<line> -- set a breakpoint at a line");
- out.println("up [n frames] -- move up a thread's stack");
- out.println("down [n frames] -- move down a thread's stack");
- out.println("clear <class id>:<line> -- clear a breakpoint");
- out.println("step -- execute current line");
- out.println("cont -- continue execution from breakpoint\n");
- out.println("catch <class id> -- break for the specified exception");
- out.println("ignore <class id> -- ignore when the specified exception\n");
- out.println("list [line number] -- print source code");
- out.println("use [source file path] -- display or change the source path\n");
- out.println("memory -- report memory usage");
- out.println("gc -- free unused objects\n");
- out.println("load classname -- load Java class to be debugged");
- out.println("run <class> [args] -- start execution of a loaded Java class");
- // out.println("kill <thread(group)> -- kill a thread or threadgroup\n");
- out.println("!! -- repeat last command");
- out.println("help (or ?) -- list commands");
- out.println("exit (or quit) -- exit debugger");
- }
-
- void executeCommand(StringTokenizer t) {
- String cmd = t.nextToken().toLowerCase();
-
- try {
- if (cmd.equals("print")) {
- print(t, false, false);
- } else if (cmd.equals("dump")) {
- print(t, true, false);
- } else if (cmd.equals("locals")) {
- locals();
- } else if (cmd.equals("classes")) {
- classes();
- } else if (cmd.equals("methods")) {
- methods(t);
- } else if (cmd.equals("threads")) {
- threads(t);
- } else if (cmd.equals("thread")) {
- thread(t);
- } else if (cmd.equals("suspend")) {
- suspend(t);
- } else if (cmd.equals("resume")) {
- resume(t);
- } else if (cmd.equals("threadgroups")) {
- threadGroups();
- } else if (cmd.equals("threadgroup")) {
- threadGroup(t);
- } else if (cmd.equals("catch")) {
- catchException(t);
- } else if (cmd.equals("ignore")) {
- ignoreException(t);
- } else if (cmd.equals("cont")) {
- cont();
- } else if (cmd.equals("step")) {
- step();
- } else if (cmd.equals("next")) {
- next();
- } else if (cmd.equals("kill")) {
- kill(t);
- } else if (cmd.equals("where")) {
- where(t);
- } else if (cmd.equals("up")) {
- up(t);
- } else if (cmd.equals("down")) {
- down(t);
- } else if (cmd.equals("load")) {
- load(t);
- } else if (cmd.equals("run")) {
- run(t);
- } else if (cmd.equals("memory")) {
- memory();
- } else if (cmd.equals("gc")) {
- gc();
- } else if (cmd.equals("trace") || cmd.equals("itrace")) {
- trace(cmd, t);
- } else if (cmd.equals("stop")) {
- stop(t);
- } else if (cmd.equals("clear")) {
- clear(t);
- } else if (cmd.equals("list")) {
- list(t);
- } else if (cmd.equals("use")) {
- use(t);
- } else if (cmd.equals("help") || cmd.equals("?")) {
- help();
- } else if (cmd.equals("quit") || cmd.equals("exit")) {
- debugger.close();
- System.exit(0);
- } else {
- out.println("huh? Try help...");
- }
- } catch (Exception e) {
- out.println("Internal exception:");
- out.flush();
- e.printStackTrace();
- }
- }
-
- void readCommandFile(File f) {
- try {
- if (f.canRead()) {
- // Process initial commands.
- DataInputStream inFile =
- new DataInputStream(new FileInputStream(f));
- String ln;
- while ((ln = inFile.readLine()) != null) {
- StringTokenizer t = new StringTokenizer(ln);
- if (t.hasMoreTokens()) {
- executeCommand(t);
- }
- }
- }
- } catch (IOException e) {}
- }
-
- public TTY(String host, String password, String javaArgs, String args,
- PrintStream outStream, PrintStream consoleStream,
- boolean verbose) throws Exception {
- System.out.println("Initializing jdb...");
- out = outStream;
- console = consoleStream;
- if (password == null) {
- debugger = new RemoteDebugger(javaArgs, this, verbose);
- } else {
- debugger = new RemoteDebugger(host, password, this, verbose);
- }
- DataInputStream in = new DataInputStream(System.in);
- String lastLine = null;
-
- if (args != null && args.length() > 0) {
- StringTokenizer t = new StringTokenizer(args);
- load(t);
- lastArgs = args;
- }
-
- Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
-
- // Try reading user's startup file.
- File f = new File(System.getProperty("user.home") +
- System.getProperty("file.separator") + "jdb.ini");
- if (!f.canRead()) {
- // Try opening $HOME/jdb.ini
- f = new File(System.getProperty("user.home") +
- System.getProperty("file.separator") + ".jdbrc");
- }
- readCommandFile(f);
-
- // Try opening local jdb.ini
- f = new File(System.getProperty("user.dir") +
- System.getProperty("file.separator") + "startup.jdb");
- readCommandFile(f);
-
- // Process interactive commands.
- while (true) {
- printPrompt();
- String ln = in.readLine();
- if (ln == null) {
- out.println("Input stream closed.");
- return;
- }
-
- if (ln.startsWith("!!") && lastLine != null) {
- ln = lastLine + ln.substring(2);
- out.println(ln);
- }
-
- StringTokenizer t = new StringTokenizer(ln);
- if (t.hasMoreTokens()) {
- lastLine = ln;
- executeCommand(t);
- }
- }
- }
-
- public static void main(String argv[]) {
- // Get host attribute, if any.
- String localhost;
- try {
- localhost = InetAddress.getLocalHost().getHostName();
- } catch (Exception ex) {
- localhost = null;
- }
- if (localhost == null) {
- localhost = "localhost";
- }
- String host = null;
- String password = null;
- String classArgs = "";
- String javaArgs = "";
- boolean verbose = false;
-
- for (int i = 0; i < argv.length; i++) {
- String token = argv[i];
- if (token.equals("-dbgtrace")) {
- verbose = true;
- } else if (token.equals("-cs") || token.equals("-checksource") ||
- token.equals("-noasyncgc") || token.equals("-prof") ||
- token.equals("-v") || token.equals("-verbose") ||
- token.equals("-verify") || token.equals("-noverify") ||
- token.equals("-verifyremote") ||
- token.equals("-verbosegc") ||
- token.startsWith("-ms") || token.startsWith("-mx") ||
- token.startsWith("-ss") || token.startsWith("-oss") ||
- token.startsWith("-D")) {
- javaArgs += token + " ";
- } else if (token.equals("-classpath")) {
- if (i == (argv.length - 1)) {
- System.out.println("No classpath specified.");
- System.exit(1);
- }
- javaArgs += token + " " + argv[++i] + " ";
- } else if (token.equals("-host")) {
- if (i == (argv.length - 1)) {
- System.out.println("No host specified.");
- System.exit(1);
- }
- host = argv[++i];
- } else if (token.equals("-password")) {
- if (i == (argv.length - 1)) {
- System.out.println("No password specified.");
- System.exit(1);
- }
- password = argv[++i];
- } else {
- classArgs += token + " ";
- }
- }
- if (host != null && password == null) {
- System.out.println("A debug password must be specified for " +
- "remote debugging.");
- System.exit(1);
- }
- if (host == null) {
- host = localhost;
- }
-
- try {
- if (!host.equals(localhost) && password.length() == 0) {
- System.out.println(
- "No password supplied for accessing remote " +
- "Java interpreter.");
- System.out.println(
- "The password is reported by the remote interpreter" +
- "when it is started.");
- System.exit(1);
- }
- new TTY(host, password, javaArgs, classArgs,
- System.out, System.out, verbose);
- } catch(SocketException se) {
- System.out.println("Failed accessing debugging session on " +
- host + ": invalid password.");
- } catch(NumberFormatException ne) {
- System.out.println("Failed accessing debugging session on " +
- host + ": invalid password.");
- } catch(Exception e) {
- System.out.print("Internal exception: ");
- System.out.flush();
- e.printStackTrace();
- }
- }
- }
-